<?php

declare(strict_types=1);

namespace App\Controller\MchApi;

use App\Constants\XZXResponseCode;
use App\Exception\XZXValidationException;
use App\Middleware\MchApi\MchJWTAuthMiddleware;
use App\Model\Enum\OrderDetailDisEnum;
use App\Model\Enum\OrderDetailFrozenEnum;
use App\Model\Enum\OrderDetailRefundEnum;
use App\Model\Enum\OrderDetailSettleStatusEnum;
use App\Model\Enum\OrderDetailThawEnum;
use App\Service\SysExportLogService;
use App\Service\TradeOrderDetailService;
use App\Utils\CustomUtils;
use App\Utils\DateUtils;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\PostMapping;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\Logger\LoggerFactory;
use Hyperf\Utils\Arr;
use Hyperf\Validation\Contract\ValidatorFactoryInterface;
use Hyperf\Contract\TranslatorInterface;

/**
 * Class TradeOrderDetailController
 *
 * @package App\Controller
 * @Controller(prefix="/mch/api/tradeOrderDetail")
 */
class TradeOrderDetailController extends MchBaseController {
    /**
     * @Inject
     * @var TranslatorInterface
     */
    private $translator;

    /**
     * @Inject()
     * @var ValidatorFactoryInterface
     */
    protected $validationFactory;

    /**
     * @Inject()
     * @var TradeOrderDetailService
     */
    protected $TradeOrderDetailService;

    /**
     * @Inject()
     * @var SysExportLogService
     */
    protected $SysExportLogService;

    /**
     * @var \Psr\Log\LoggerInterface
     */
    protected $logger;

    public function __construct (LoggerFactory $loggerFactory) {
        // 第一个参数对应日志的 name, 第二个参数对应 config/autoload/logger.php 内的 key
        $this->logger = $loggerFactory->get('log', 'default');
    }

    private function setLocale () {
        if ($this->request->header('locale') == 'en') {
            $this->translator->setLocale('en');
        }
    }

    /**
     * 查看
     * @PostMapping(path = "get")
     * @Middleware(MchJWTAuthMiddleware::class)
     */
    public function get (RequestInterface $request) {
        $this->setlocale();
        $validator = $this->validationFactory->make($request->all(), [
            'id' => 'required',
        ]);

        if ($validator->fails()) {
            // Handle exception
            $errorMessage = $validator->errors()->first();
            throw new XZXValidationException($errorMessage);
        }

        $param           = $request->all();
        $ext             = $this->request->getAttribute("ext");
        $param['mchId']  = $ext['mchId'];
        $param['source'] = 1;
        return $this->TradeOrderDetailService->get($param);
    }

    /**
     * 退款options
     * @PostMapping(path = "isRefundOption")
     * @Middleware(MchJWTAuthMiddleware::class)
     */
    public function isRefundOption (RequestInterface $request) {
        $data = (new OrderDetailRefundEnum())->getOptions();
        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE, XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE), $data);
    }

    /**
     * 拒付options
     * @PostMapping(path = "isDisOption")
     * @Middleware(MchJWTAuthMiddleware::class)
     */
    public function isDisOption (RequestInterface $request) {
        $data = (new OrderDetailDisEnum())->getOptions();
        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE, XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE), $data);
    }

    /**
     * 冻结options
     * @PostMapping(path = "isFrozenOption")
     * @Middleware(MchJWTAuthMiddleware::class)
     */
    public function isFrozenOption (RequestInterface $request) {
        $data = (new OrderDetailFrozenEnum())->getOptions();
        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE, XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE), $data);
    }

    /**
     * 解冻options
     * @PostMapping(path = "isThawOption")
     * @Middleware(MchJWTAuthMiddleware::class)
     */
    public function isThawOption (RequestInterface $request) {
        $data = (new OrderDetailThawEnum())->getOptions();
        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE, XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE), $data);
    }

    /**
     * 结算options
     * @PostMapping(path = "isSettleOption")
     * @Middleware(MchJWTAuthMiddleware::class)
     */
    public function isSettleOption (RequestInterface $request) {
        $data = (new OrderDetailSettleStatusEnum())->getOptions();
        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE, XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE), $data);
    }

    /**
     * 查询
     * @PostMapping(path = "list")
     * @Middleware(MchJWTAuthMiddleware::class)
     */
    public function list (RequestInterface $request) {
        $this->setlocale();
        $validator = $this->validationFactory->make($request->all(), [
            'page'  => 'required|integer|min:1',
            'limit' => 'required|integer|min:1',
        ]);

        if ($validator->fails()) {
            // Handle exception
            $errorMessage = $validator->errors()->first();
            throw new XZXValidationException($errorMessage);
        }

        $param           = $request->all();
        $ext             = $this->request->getAttribute("ext");
        $param['mchId']  = $ext['mchId'];
        $param['source'] = 1;

        if (isset($param['search'])) {
            $search = $param['search'];
            CustomUtils::xzxAddSearch($param, $search, 'tradeNo');
            CustomUtils::xzxAddSearch($param, $search, 'orderNo');
            CustomUtils::xzxAddSearch($param, $search, 'relNo');
            CustomUtils::xzxAddSearch($param, $search, 'mchUrl');
            CustomUtils::xzxAddSearch($param, $search, 'transStatus');
            CustomUtils::xzxAddSearch($param, $search, 'isSettle');
            CustomUtils::xzxAddSearch($param, $search, 'isRefund');
            CustomUtils::xzxAddSearch($param, $search, 'isDis');
            CustomUtils::xzxAddSearch($param, $search, 'isFrozen');
            CustomUtils::xzxAddSearch($param, $search, 'isThaw');
            CustomUtils::xzxAddSearch($param, $search, 'channelId');
            CustomUtils::xzxAddSearch($param, $search, 'createTimeRange');
            if (isset($param["createTimeRange"])) {
                try {
                    $param['createTimeRange'][0] = DateUtils::dateToTimeStamp($param['createTimeRange'][0]);
                    $param['createTimeRange'][1] = DateUtils::dateToTimeStamp($param['createTimeRange'][1]);
                } catch (\Throwable $th) {
                    unset($param['createTimeRange']);
                }
            }
        }

        $ext            = $this->request->getAttribute("ext");
        $param['mchId'] = $ext['mchId'];
        return $this->TradeOrderDetailService->list($param);
    }

    /**
     * 导出
     * @PostMapping(path = "exportExcel")
     * @Middleware(MchJWTAuthMiddleware::class)
     *
     * @param RequestInterface $request
     *
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     * @throws \Throwable
     * @throws \TypeError
     * @return array|mixed
     */
    public function exportExcel (RequestInterface $request) {
        $this->setlocale();
        $type = 1;
        $ext  = $this->request->getAttribute("ext");

        $param = [
            'page'  => 1,
            'limit' => 1e7,
            'mchId' => $ext['mchId'],
        ];

        $search = $request->post('search', []);

        CustomUtils::xzxAddSearch($param, $search, 'tradeNo');
        CustomUtils::xzxAddSearch($param, $search, 'orderNo');
        CustomUtils::xzxAddSearch($param, $search, 'relNo');
        CustomUtils::xzxAddSearch($param, $search, 'mchUrl');
        CustomUtils::xzxAddSearch($param, $search, 'transStatus');
        CustomUtils::xzxAddSearch($param, $search, 'isSettle');
        CustomUtils::xzxAddSearch($param, $search, 'isRefund');
        CustomUtils::xzxAddSearch($param, $search, 'isDis');
        CustomUtils::xzxAddSearch($param, $search, 'isFrozen');
        CustomUtils::xzxAddSearch($param, $search, 'isThaw');
        CustomUtils::xzxAddSearch($param, $search, 'channelId');
        CustomUtils::xzxAddSearch($param, $search, 'createTimeRange');

        if (isset($param["createTimeRange"])) {
            try {
                $param['createTimeRange'][0] = DateUtils::dateToTimeStamp($param['createTimeRange'][0]);
                $param['createTimeRange'][1] = DateUtils::dateToTimeStamp($param['createTimeRange'][1]);
            } catch (\Throwable $th) {
                unset($param['createTimeRange']);
            }
        }

        // 新增导出记录
        $result = $this->SysExportLogService->add(['type' => $type, 'createBy' => $ext['createBy']]);

        $logId    = $result['data'];
        $fileName = 'order-'.date('YmdHis').rand(1000, 9999);
        $xlsCell  = [
            ['filed' => 'mchNo', 'name' => trans('export.order-detail.col.mch-no')],
            ['filed' => 'tradeNo', 'name' => trans('export.order-detail.col.trade-no')],
            ['filed' => 'orderNo', 'name' => trans('export.order-detail.col.order-no')],
            ['filed' => 'mchTransTime', 'name' => trans('export.order-detail.col.mch-trans-time')],
            ['filed' => 'floatMchTransAmount', 'name' => trans('export.order-detail.col.mch-trans-amount')],
            ['filed' => 'mchTransCurrency', 'name' => trans('export.order-detail.col.mch-trans-currency')],
            ['filed' => 'floatSettleAmount', 'name' => trans('export.order-detail.col.settle-amount')],
            ['filed' => 'settleCurrency', 'name' => trans('export.order-detail.col.settle-currency')],
            ['filed' => 'floatServiceFee', 'name' => trans('export.order-detail.col.service-fee')],
            ['filed' => 'floatPerFee', 'name' => trans('export.order-detail.col.per-fee')],
            ['filed' => 'settleCurrency', 'name' => trans('export.order-detail.col.fee-currency')],
            ['filed' => 'floatBondAmount', 'name' => trans('export.order-detail.col.bond-amount')],
            ['filed' => 'settleCurrency', 'name' => trans('export.order-detail.col.bond-currency')],
            ['filed' => 'strTransStatus', 'name' => trans('export.order-detail.col.trans-status')],
            ['filed' => 'strIsDis', 'name' => trans('export.order-detail.col.is-dis')],
            ['filed' => 'floatDisAmount', 'name' => trans('export.order-detail.col.dis-amount')],
            ['filed' => 'strIsRefund', 'name' => trans('export.order-detail.col.is-refund')],
            ['filed' => 'floatRefundAmount', 'name' => trans('export.order-detail.col.refund-amount')],
            ['filed' => 'strIsFrozen', 'name' => trans('export.order-detail.col.is-frozen')],
            ['filed' => 'floatFrozenAmount', 'name' => trans('export.order-detail.col.frozen-amount')],
            ['filed' => 'mchUrl', 'name' => trans('export.order-detail.col.mch-url')],
        ];


        $this->SysExportLogService->addToTask([
            'logId'    => $logId,
            'fileName' => $fileName,
            'type'     => $type,
            'param'    => $param,
            'xlsCell'  => $xlsCell,
            'locale'   => $this->translator->getLocale(),
        ]);

        return $result;
    }
}
